package voxToolkit;

import grafico.Fabrica;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import audio.AudioSintetizado;

public class VoxFileChooser extends JDialog implements ListSelectionListener, ActionListener, KeyListener, FocusListener{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private VoxListFiles lista_dirs;
	private VoxList lista_arqs;
	private VoxTextField arqSelecionado;
	private VoxTextField caminhoAtual;
	private VoxButton btOk;
	private VoxButton btCancel;
	public int APPROVE_OPTION = 0;
	private String rotulo;
	private AudioSintetizado sintetizador;
	private Boolean jaFalou = false;
	
	/**
	 * Cria um diálogo de abrir arquivo sem filtro.
	 * Apenas cria o objeto, mas não exibe o diálogo; para exibir,
	 * utilizar showSaveDialog ou showOpenDialog.
	 */
	public VoxFileChooser(){
		lista_dirs = new VoxListFiles(modelRaiz(),"diretórios");
		this.addFocusListener(this);
	}
	
	/**
	 * Cria um diálogo de abrir arquivo com o filtro.
	 * Apenas cria o objeto, mas não exibe o diálogo; para exibir,
	 * utilizar showSaveDialog ou showOpenDialog.
	 * @param filtro
	 */
	public VoxFileChooser(String filtro){
		lista_dirs = new VoxListFiles(modelRaiz(),"diretórios",filtro);
		this.addFocusListener(this);
		this.setFocusable(true);
	}
	
	/**
	 * Abre um diálogo para abrir arquivo.
	 */
	public void showOpenFile(){
		botoesAbrir();
		rotulo = "Diálogo para abrir arquivo. ";
		montaGUI();
		setVisible(true);
		
	}
	
	/**
	 * Abre um diálogo para salvar arquivo.
	 */
	public void showSaveFile(){
		botoesSalvar();
		rotulo = "Diálogo para salvar arquivo. ";
		montaGUI();		
		setVisible(true);
	}
	
	private DefaultListModel modelRaiz(){
		DefaultListModel model = new DefaultListModel();
		File[] f = File.listRoots();
		for (int i=0;i<f.length;i++)
			model.addElement(f[i].toString());
		return model;
	}
	
	public String getRotulo(){
		return rotulo;
	}
	
	public Boolean getJaFalou(){
		return jaFalou;
	}
	
	public void setJaFalou(Boolean falou){
		this.jaFalou = falou;
	}
	
	public void montaGUI(){
		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		this.setSize(new Dimension(700,500));
	
		Container principal = this.getContentPane();
		principal.setLayout(new BoxLayout(principal,BoxLayout.Y_AXIS));
		principal.setBackground(Fabrica.background);
		principal.addFocusListener(this);
		
		JPanel painel_superior = Fabrica.painelFundoAzul();
		principal.add(painel_superior);
		caminhoAtual = new VoxTextField("Caminho");
		caminhoAtual.setMinimumSize(new Dimension(420,50));
		caminhoAtual.setPreferredSize(new Dimension(420,50));
		painel_superior.add(caminhoAtual);
		caminhoAtual.setText("");
		
		JPanel painel_centro = Fabrica.painelFundoAzul();
		painel_centro.setLayout(new BoxLayout(painel_centro,BoxLayout.X_AXIS));
		principal.add(painel_centro);
		JPanel painel_inferior = Fabrica.painelFundoAzul();
		principal.add(painel_inferior);
		
		JPanel painel_esquerda = Fabrica.painelFundoAzul();
		painel_esquerda.setLayout(new BoxLayout(painel_esquerda,BoxLayout.Y_AXIS));
		painel_esquerda.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));

		JLabel lbDirs = Fabrica.labelBranco("Diretórios");
		lbDirs.setFocusable(false);
		painel_esquerda.add(lbDirs);
		lista_dirs.setSize(400, 300);
		lista_dirs.addListSelectionListener(this);
		JScrollPane scroll_pn = new JScrollPane(lista_dirs);
		painel_esquerda.add(scroll_pn);

		painel_centro.add(painel_esquerda);
		
		JPanel painel_direita = Fabrica.painelFundoAzul();
		painel_direita.setLayout(new BoxLayout(painel_direita,BoxLayout.Y_AXIS));
		painel_direita.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		painel_centro.add(painel_direita);
		JLabel lbArqs = Fabrica.labelBranco("Arquivos");
		lbArqs.setFocusable(false);
		painel_direita.add(lbArqs);
		DefaultListModel model_arqs = new DefaultListModel();
		lista_arqs = new VoxList(model_arqs,"arquivos");
		lista_dirs.addList(lista_arqs);
		lista_arqs.setSize(100, 300);
		lista_arqs.addListSelectionListener(this);
		JScrollPane scroll_pn2 = new JScrollPane(lista_arqs);
		painel_direita.add(scroll_pn2);
		
		arqSelecionado = new VoxTextField("arquivo selecionado ");
		arqSelecionado.setMinimumSize(new Dimension(300,50));
		arqSelecionado.setPreferredSize(new Dimension(500,50));
		arqSelecionado.setFont(Fabrica.fonteMedia);
		painel_inferior.add(arqSelecionado);
		painel_inferior.add(btOk);
		painel_inferior.add(btCancel);
		
		setModal(true);
		
	}
	
	private void botoesAbrir(){
		btOk = new VoxButton("ok", "Abrir");
		btOk.addActionListener(this);
		btOk.addKeyListener(this);
		btCancel = new VoxButton("cancel", "Cancelar");
		btCancel.addActionListener(this);
		btCancel.addKeyListener(this);
	}
	
	private void botoesSalvar(){
		btOk = new VoxButton("ok", "Salvar");
		btOk.addActionListener(this);
		btOk.addKeyListener(this);
		btCancel = new VoxButton("cancel", "Cancelar");
		btCancel.addActionListener(this);
		btCancel.addKeyListener(this);
	}
	
	/**
	 * Retorna o arquivo selecionado no diálogo ou null caso
	 * nenhum arquivo tenha sido selecionado.
	 * @return
	 */
	public File getArquivoSelecionado(){
		File selecionado = new File(lista_dirs.caminhoAtual()+arqSelecionado.getText());
		if (arqSelecionado.getText().equals(""))
			return null;
		else
			return selecionado;
	}

	/**
	 * Realiza a ação correspondente a cada botão. Botão "ok" torna
	 * APPROVE_OPTION = 1 e fecha o diálogo, botão "cancel" torna
	 * APPROVE_OPTION = 0 e fecha o diálogo.
	 * @param botao
	 */
	public void acaoBotao(VoxButton botao){
		if (botao.getNome().equals("ok")){
			APPROVE_OPTION = 1;
			dispose();			
		}
		else if (botao.getNome().equals("cancel")){
			dispose();		
			APPROVE_OPTION = 0;
		}
	}
	
	@Override
	public void valueChanged(ListSelectionEvent event) {

		caminhoAtual.setText(lista_dirs.caminhoAtual());
		if (event.getSource() instanceof VoxList){
			VoxList lista = (VoxList) event.getSource();
			if (lista.getRotulo().equals("arquivos")){
				if (! lista.isSelectionEmpty()){
					int indice = lista.getSelectedIndex();
					arqSelecionado.setText(lista.getModel().getElementAt(indice).toString());					
				}
			}	
		}	
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() instanceof VoxButton){
			/*getArquivoSelecionado();
			this.dispose();*/
			acaoBotao( (VoxButton)e.getSource() );
		}
		
	}

	@Override
	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyReleased(KeyEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		//"enter" no botão executa a ação do botão
		if (e.getKeyChar() == KeyEvent.VK_ENTER)
		{
			if ( e.getSource() instanceof VoxButton )
			{			
				acaoBotao( (VoxButton)e.getSource() );
			}
		}
		//a tecla "C" é um atalho para o sintetizador falar o caminho atual
		if (e.getKeyChar() == KeyEvent.VK_F2){
			System.out.println("Caminho atual: "+caminhoAtual);
		}
	}

	@Override
	public void focusGained(FocusEvent e) {
		
		if ( e.getSource() instanceof Container ){
		
			//Precisamos saber se tem necessidade de falar o rótulo cada vez que
			// o "tab" passar pela caixa ou se tem que falar somente na hora
			// em que abre a caixa de dialogo.
			// Caso fale somente quando abre, mantêm o codigo com a variavel
			// jaFalou, caso fale toda vez que ganhar foco, ela (e os métodos correspondentes)
			// podem ser retiradas.
			
			if (!(getJaFalou())){
				
				sintetizador = AudioSintetizado.instancia();
				sintetizador.escreve(this.getRotulo() + ". ");
				caminhoAtual.requestFocus();
				this.setJaFalou(true);
				
			}
		}
	}

	@Override
	public void focusLost(FocusEvent arg0) {
		
		
	}

}
